﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using System.Reflection;
using DataAccessor.Protector;

namespace DataAccessor
{
    /// <summary>
    /// SQL配置文件解析类
    /// </summary>
    public class TSQLParser
    {
        #region 成员变量
        /// <summary>
        /// T-SQL配置文件
        /// </summary>
        private readonly XmlDocument _tsqlXML;
        /// <summary>
        /// T-SQL配置的所有语句块
        /// </summary>
        private TSQLStatement[] _statementArray;
        /// <summary>
        /// T-SQL配置
        /// </summary>
        private TSQL _TSQL = null;
        /// <summary>
        /// T-SQL保护算法
        /// </summary>
        private IProtector _protector = null;
        #endregion

        #region 常量
        private static object PARSER_LOCK = new object();
        #endregion

        /// <summary>
        /// 创建TSQLParser的一个实例
        /// </summary>
        public TSQLParser(XmlDocument tsqlXML, IProtector protector = null)
        {
            _tsqlXML = tsqlXML;
            _protector = protector;
            Parser();
        }

        /// <summary>
        /// 从指定的SQL配置文件创建TSQLParser的一个实例
        /// </summary>
        public TSQLParser(string tsqlFilePath, IProtector protector = null)
        {
            _tsqlXML = new XmlDocument();
            _protector = protector;
            LoadTSQLXML(tsqlFilePath);
            Parser();
        }

        /// <summary>
        /// 加载XML文件到XMLDocument
        /// </summary>
        /// <param name="tsqlFilePath"></param>
        private void LoadTSQLXML(string tsqlFilePath)
        {
            if (string.IsNullOrEmpty(tsqlFilePath))
            {
                throw new NullReferenceException("请指定TSQL配置文件路径。");
            }

            if (!File.Exists(tsqlFilePath))
            {
                throw new FileNotFoundException("没有找到文件：" + tsqlFilePath);
            }

            // 解密T-SQL文件
            if (_protector != null)
            {
                var tempFile = Path.GetTempFileName();
                _protector.DecryptTSQLFile(tsqlFilePath, tempFile);
                tsqlFilePath = tempFile;
            }

            _tsqlXML.Load(tsqlFilePath);
        }

        /// <summary>
        /// 解析XML文件
        /// </summary>
        private void Parser()
        {
            var bytes = UnicodeEncoding.UTF8.GetBytes(_tsqlXML.InnerXml);
            var stream = new MemoryStream(bytes);

            var serializer = new XmlSerializer(typeof(TSQL));
            try
            {
                _TSQL = serializer.Deserialize(stream) as TSQL;
            }
            catch (Exception ex)
            {
                throw new XmlException("反序列化T-SQL.xml失败", ex);
            }
            finally
            {
                stream.Close();
                stream.Dispose();
            }
            _statementArray = _TSQL.Statement;
        }

        /// <summary>
        /// 获取TSQL配置的所有语句块
        /// </summary>
        public TSQLStatement[] StatementArray
        {
            get { return _statementArray; }
        }
        /// <summary>
        /// 获取TSQL节点
        /// </summary>
        public TSQL TSQL
        {
            get { return _TSQL; }
        }
    }
}
